<!DOCTYPE html>
<html lang="en">
<head>
    <meta charset="UTF-8">
    <title>星级评分--第一种实现方式3</title>
    <style>
        body,ul,li{
            padding: 0;
            margin: 0;
        }
        li {
            list-style-type: none;
        }
        .rating {
            width: 160px;
            height: 32px;
            margin: 100px auto;
        }
        .rating-item {
            float: left;
            width: 32px;
            height: 32px;
            background: url("img/rating.png") no-repeat;
            cursor: pointer;
        }
    </style>
</head>
<body>

    <!-- 第一种实现方式 -->
    <ul id="rating" class="rating">
        <li class="rating-item" title="很不好"></li>
        <li class="rating-item" title="不好"></li>
        <li class="rating-item" title="一般"></li>
        <li class="rating-item" title="好"></li>
        <li class="rating-item" title="很好"></li>
    </ul>


    <ul id="rating2" class="rating">
        <li class="rating-item" title="很不好"></li>
        <li class="rating-item" title="不好"></li>
        <li class="rating-item" title="一般"></li>
        <li class="rating-item" title="好"></li>
        <li class="rating-item" title="很好"></li>
    </ul>

    <script src="http://libs.baidu.com/jquery/2.0.0/jquery.min.js"></script>
    <script>

        var rating = (function() {
            // 继续
            var extend = function(subClass, superClass) {
                var F = function() {}
                F.prototype = superClass.prototype
                subClass.prototype = new F()
                subClass.prototype.constructor = subClass
            }

            // 抽象父类
            // 点亮
            var Light = function (el, options) {
                this.$el = $(el);
                this.$item = this.$el.find('.rating-item');
                this.opts = options;
                this.add = 1
                this.selectEvent = 'mouseover'
            }
            Light.prototype.init = function() {
                this.lightOn(this.opts.num)
                // 不是只读才能绑定事件
                if (!this.opts.readOnly) {
                    this.bindEvent();
                }
            };

            Light.prototype.lightOn = function(num) {
                num = parseInt(num)
                this.$item.each(function(index) {
                    if (index < num) {
                        $(this).css('background-position', '0 -40px')
                    } else {
                        $(this).css('background-position', '0 0')
                    }
                })
            }
            // 绑定事件
            Light.prototype.bindEvent = function () {
                var self = this,
                    itemLength = self.$item.length
                self.$el.on(self.selectEvent, '.rating-item', function(e) {
                    var $this = $(this),
                        num = 0;

                    self.select(e, $this)
                    num = $(this).index() + self.add;
                    self.lightOn(num);
                    (typeof self.opts.select === 'function') && self.opts.select.call(this, num, itemLength);
                    self.$el.trigger('select', [num, itemLength])
                }).on('click', '.rating-item', function() {
                    self.opts.num = $(this).index() + self.add;
                    (typeof self.opts.chosen === 'function') && self.opts.chosen.call(this, self.opts.num, itemLength);
                    self.$el.trigger('chosen', [self.opts.num, itemLength])
                }).on('mouseout', function () {
                    self.lightOn(self.opts.num);
                })
            }
            Light.prototype.select = function () {
                throw new Error('子类必须重写此方法')
            }

            Light.prototype.unbindEvent = function () {
                this.$el.off()
            }

            // --------------------------------------------------
            // 点亮整颗星星
            var LightEntire = function (el, options) {
                Light.call(this, el, options);
                this.selectEvent = 'mouseover'
            }

            extend(LightEntire, Light);

            LightEntire.prototype.lightOn = function(num) {
                Light.prototype.lightOn.call(this, num)
            }
            LightEntire.prototype.select = function () {
                self.add = 1
            }
            // ------------------------------------------------------------------------------------------------------------

            // 点亮半颗星星
            var LightHalf = function (el, options) {
                Light.call(this, el, options);
                this.selectEvent = 'mousemove'
            }
            extend(LightHalf, Light);
            LightHalf.prototype.lightOn = function(num) {
                // 是否选择的是半颗
                var count = parseInt(num),
                    isHalf = count !== num;


                Light.prototype.lightOn.call(this, count)
                // 半颗点亮
                if (isHalf) {
                    this.$item.eq(count).css('background-position', '0 -80px')
                }
            }

            LightHalf.prototype.select = function (e, $this) {
                if (e.pageX - $this.offset().left < $this.width() / 2) {// 半颗
                    this.add = 0.5
                } else { // 整颗
                    this.add = 1;
                }
            }



            // 默认参数
            var defaults = {
                 mode: 'LightEntire', // 选择点亮半颗或者整颗的模式
                 num: 0,
                 readOnly: false,
                 select: function() {},
                 chosen: function() {}
            }

            var mode = {
                'LightEntire': LightEntire,
                'LightHalf': LightHalf
            }

            //. 初始化
            var init = function (el, option) {
                var $el = $(el),
                    rating = $el.data('rating'),
                    options = $.extend({}, defaults, typeof option === 'object' && option);
                // new LightEntire(el, options).init()
                // new LightHalf(el, options).init()
                if (!mode[options.mode]) {
                    options.mode = 'LightEntire'
                }
                if (!rating) {
                    $el.data('rating', (rating = new mode[options.mode](el, options)));
                    rating.init()
                }
                if (typeof option === 'string') rating[option]()
            };
            // 注册成为JQuery插件来使用
            $.fn.extend({
                rating: function(option) {
                    return this.each(function() {
                        init(this, option)
                    })
                }
            })
            return {
                init: init
            }
        })()

        // 在页面中的测试代码
        $('#rating').rating({
            mode: 'LightEntire',
            num: 2,
        })
        $('#rating2').rating({
            mode: 'LightHalf',
            num: 3.5
        })

        $('#rating2').on('chosen', function() {
            $('#rating2').rating('unbindEvent')
        })


        // rating.init('#rating', {
        //     mode: 'LightHalf',
        //     num: 2.5,
        //     // select: function(num, total) {
        //     //     console.log(this)
        //     //     console.log(num + '/' + total)
        //     // }
        //     chosen: function() {
        //         rating.init('#rating', 'unbindEvent')
        //     }
        // });
        // $('#rating').on('select', function(e, num, total){
        //     console.log(num + '/' + total)
        // }).on('chosen', function (e, num, total) {
        //     console.log(num + '/' + total)
        // })


        // var rating = (function(){
        //     // 点亮
        //     var lightOn = function ($item, num) {
        //         $item.each(function(index) {
        //             if (index < num) {
        //                 $(this).css('background-position', '0 -40px')
        //             } else {
        //                 $(this).css('background-position', '0 0')
        //             }
        //         })
        //     }
        //     // 初始化函数
        //     var init = function(el, num){
        //         // 初始化点亮 2颗星星
        //         var $rating = $(el),
        //             $item = $rating.find('.rating-item');
        //
        //         // 初始化
        //         lightOn($item, num)
        //
        //         // 事件绑定 事件委托的写法
        //         $rating.on('mouseover', '.rating-item', function() {
        //             lightOn($item, $(this).index() + 1)
        //         }).on('click', '.rating-item', function() {
        //             num = $(this).index() + 1
        //         }).on('mouseout', function () {
        //             lightOn($item, num)
        //         })
        //     }
        //     // jQuery插件
        //     $.fn.extend({
        //         rating: function(num) {
        //             return this.each(function() {
        //                 init(this, num)
        //             })
        //         }
        //     })
        //     return {
        //         init: init
        //     }
        //
        // })()
        // $('#rating').rating(4)

    </script>

</body>
</html>
